package com.woniu.scss.service.impl;

import com.woniu.scss.dto.AddrDTO;
import com.woniu.scss.pojo.Logistics;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.extension.api.R;
import com.google.common.collect.Lists;
import com.woniu.common.utils.SnowflakeIdGenerator;
import com.woniu.scss.dto.*;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.woniu.common.utils.PageParam;
import com.woniu.common.utils.ResponseData;
import com.woniu.scss.feign.CustomerFeign;
import com.woniu.scss.feign.OrderFeign;
import com.woniu.scss.mapper.LogisticsMapper;
import com.woniu.scss.mapper.PaymentMapper;
import com.woniu.scss.pojo.*;
import com.woniu.scss.service.*;
import com.woniu.scss.vo.DeliverGoodsVO;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.woniu.scss.mapper.OrderMapper;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.RequestParam;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderMapper, Order> implements OrderService {

    @Autowired
    private OrderFeign orderFeign;

    @Autowired
    private PaymentService paymentService;

    @Autowired
    private OrderMapper orderMapper;

    @Autowired
    private OrderDetailService orderDetailService;

    @Autowired
    private CustomerFeign customerFeign;

    @Autowired
    private LogisticsCompanyService logisticsCompanyService;

    @Autowired
    private LogisticsService logisticsService;
    @Autowired
    private ProductService productService;


    @Override
    public ResponseData<?> selPayMethod() {
        List<Payment> list = paymentService.lambdaQuery()
                .list();
        return new ResponseData<>().success(list);
    }

    @Override
    public ResponseData<?> searchOrderByCondition(PageParam<OrderSearchDTO> pageParam) {
        PageHelper.startPage(pageParam.getPageNum(), pageParam.getPageSize());
        List<Order> list = orderMapper.searchOrderByCondition(pageParam.getParam());
        PageInfo<Order> orderPageInfo = new PageInfo<>(list);
        return new ResponseData<>().success(orderPageInfo);
    }

    @Override
    public ResponseData<?> selOrderDetail(String orderId) {
        OrderDetailDTO orderDetailDTO = new OrderDetailDTO();

        Order order = lambdaQuery().eq(Order::getId, orderId)
                .one();

        List<OrderDetail> orderDetails = orderDetailService.selOrderDetail(orderId);

        for (OrderDetail orderDetail : orderDetails) {
            Product product = productService.lambdaQuery().eq(Product::getId, orderDetail.getProductId()).one();
            orderDetail.setProductImg(product.getProductImg());
        }

        orderDetailDTO.setOrder(order);
        orderDetailDTO.setOrderDetails(orderDetails);
        return new ResponseData<>().success(orderDetailDTO);
    }

    @Override
    public ResponseData<?> handleDispatchList(String orderId) {
        DispatchListDTO dispatchListDTO = new DispatchListDTO();
        Order order = lambdaQuery().eq(Order::getId, orderId)
                .one();
        dispatchListDTO.setOrder(order);
        List<OrderDetail> orderDetails = orderDetailService.selOrderDetail(orderId);
        dispatchListDTO.setOrderDetails(orderDetails);
        AddrDTO addrDTO = customerFeign.selUserAddrById(orderDetails.get(0).getAddressId());
        dispatchListDTO.setAddrDTO(addrDTO);
        return new ResponseData<>().success(dispatchListDTO);
    }

    @SneakyThrows
    @Override
    public ResponseData<?> handleDeliverGoods(String orderId) {
        DeliverGoodsVO deliverGoodsVO = new DeliverGoodsVO();
        List<LogisticsCompany> list = logisticsCompanyService.lambdaQuery().list();
        long l = new SnowflakeIdGenerator().nextId();
        deliverGoodsVO.setCourierNumber(String.valueOf(l));
        deliverGoodsVO.setLogisticsCompanies(list);
        deliverGoodsVO.setOrderId(orderId);

        List<OrderDetail> orderDetails = orderDetailService.selOrderDetail(orderId);
        AddrDTO addrDTO = customerFeign.selUserAddrById(orderDetails.get(0).getAddressId());

        deliverGoodsVO.setAddrDTO(addrDTO);

        return new ResponseData<>().success(deliverGoodsVO);
    }

    @Override
    @Transactional
    public ResponseData<?> sendOut(SendOutDTO sendOutDTO) {
        // 物流信息
        Logistics logistics = new Logistics();
        logistics.setId(sendOutDTO.getCourierNumber());
        logistics.setLogisticsCompanyId(sendOutDTO.getCompanyId());
        LogisticsCompany logisticsCompany = logisticsCompanyService.lambdaQuery()
                .eq(LogisticsCompany::getId, sendOutDTO.getCompanyId()).one();
        logistics.setLogisticsCompanyName(logisticsCompany.getLogisticsCompanyName());
        logistics.setLogisticsStatus(0);
        logistics.setFromWhere("118.827516, 31.930225");
        logistics.setLogistics("");
        logistics.setToWhere(sendOutDTO.getAddrDTO().getLongitude() + "," + sendOutDTO.getAddrDTO().getLatitude());
        logisticsService.save(logistics);
        // 订单信息
        lambdaUpdate()
                .eq(Order::getId, sendOutDTO.getOrderId())
                .set(Order::getState, 3)
                .update();
        // 订单详情
        orderDetailService.lambdaUpdate()
                .eq(OrderDetail::getOrderId, sendOutDTO.getOrderId())
                .set(OrderDetail::getLogisticsCompanyId, sendOutDTO.getCompanyId())
                .set(OrderDetail::getLogisticsName, logisticsCompany.getLogisticsCompanyName())
                .set(OrderDetail::getLogisticsId, sendOutDTO.getCourierNumber())
                .update();

        // 同步物流信息
        LogisticsInforDTO logisticsInforDTO = new LogisticsInforDTO();
        logisticsInforDTO.setLogistics(logistics);
        logisticsInforDTO.setOrderId(sendOutDTO.getOrderId());
        logisticsInforDTO.setAddrDTO(sendOutDTO.getAddrDTO());
        logisticsInforDTO.setCourierNumber(sendOutDTO.getCourierNumber());
        logisticsInforDTO.setCompanyId(sendOutDTO.getCompanyId());
        Boolean b = orderFeign.synchronousLogisticsInfo(logisticsInforDTO);
        return new ResponseData<>().success();
    }

    @Override
    public ResponseData<?> addOrderFromZy(String orderMessage) {
        Map<String, String> map = JSON.parseObject(orderMessage, Map.class);
//        Map<String, Object> map = (Map<String, Object>) JSON.parse(orderMessage);
        String orderString = map.get("order");
        Order order = JSON.parseObject(orderString, Order.class);
        save(order);
        String orderDetailListString = map.get("orderDetailList");
        List<OrderDetail> orderDetailList = JSON.parseArray(orderDetailListString, OrderDetail.class);
        orderDetailService.saveBatch(orderDetailList);


        for (OrderDetail orderDetail : orderDetailList) {
            String productId = orderDetail.getProductId();
            Integer buyNum = orderDetail.getBuyNum();
            Product product = productService.lambdaQuery().eq(Product::getId, productId).one();
            productService.lambdaUpdate()
                    .set(Product::getStock, product.getStock() - buyNum)
                    .eq(Product::getId, productId)
                    .update();
        }
        return new ResponseData<>().success();
    }

    @Override
    public boolean shouhouChangeOrderStatus(String orderId) {
        Order order = getById(orderId);
        //售后完成后，订单状态改成已取消
        order.setState(5);
        boolean b = updateById(order);
        return b;
    }

    @Override
    public boolean quxiaoShouhouChangeOrderStatus(String orderId) {
        Order order = getById(orderId);
        //售后完成后，订单状态改成已取消
        order.setState(4);
        boolean b = updateById(order);
        return b;
    }

    @Override
    public boolean shouhuoFromZy(String orderId, String orderDetailId) {
        lambdaUpdate()
                .set(Order::getState,4)
                .eq(Order::getId,orderId)
                .update();
        orderDetailService.lambdaUpdate()
                .set(OrderDetail::getState,4)
                .eq(OrderDetail::getId,orderDetailId)
                .update();
        return false;
    }


}
